<template>
  <div class="custom-table">
    <div :class="['list-operate3', {'show-more': showMore}, {'mt-0': operateMargin}]">
      <slot name="operateLeft"></slot>
      <div class="operate-right">
        <slot name="operateRight"></slot>
        <a-popover :title="null" class="custom-table-popover" placement="topRight">
          <template #content>
            <draggable v-model="columnList" chosenClass="custom-table-chosen" ghostClass="custom-table-ghost" handle=".mover" filter=".forbid" :forceFallback="true" item-key="index" @end="upDataColumn" :move="onMove"> 
              <template #item="{element, index}">
                <div :key="index" style="min-width: 100px; line-height: 28px;" :class="element.fixed ? 'forbid': ''">
                  <span class="mr-15 w-13 inline-block">
                    <span class="mover custom-table-mover" v-if="!element.fixed">
                      <HolderOutlined />
                    </span>
                  </span>
                  <a-checkbox v-model:checked="element.visibility" @change="upDataColumn" style="min-width: 100px;">
                    {{element.title}}
                  </a-checkbox>
                  <span style="float: right" class="to-fix-icon-container">
                    <PushpinFilled v-if="element.fixed" class="text-primary hover-pointer" @click="fixColumnChange(element, null)"/>
                    <span v-else class="to-fix-icon">
                      <VerticalAlignTopOutlined class="mx-8" @click="fixColumnChange(element, 'left')"/>
                      <VerticalAlignBottomOutlined @click="fixColumnChange(element, 'right')"/>
                    </span>
                  </span>
                </div>
              </template>
            </draggable>
          </template>
          <a-button class="ml-10">
            <template #icon>
              <SettingOutlined />
            </template>
          </a-button>
        </a-popover>
      </div>
    </div>
    <a-table :rowKey="props.rowKey" :customRow="props.customRow" :rowClassName="props.rowClassName" :size="props.size" :loading="props.loading" :bordered="props.bordered" :dataSource="props.dataSource" :columns="getColumns()" :rowSelection="props.rowSelection" :pagination="props.pagination" :scroll="props.scroll" @change="(pagination, filters, sorter, { currentDataSource }) => emits('change', pagination, filters, sorter, { currentDataSource })" @resizeColumn="handleResizeColumn"
             :expandIconAsCell="false"
             :expandIconColumnIndex="-1"
             :expandedRowKeys="props.expandedRowKeys"
             :defaultExpandAllRows="props.defaultExpandAllRows"
    >
      <template #headerCell="scope">
        <slot name="headerCell" :scope="scope"></slot>
      </template>
      <template #bodyCell="scope">
        <slot name="bodyCell" :scope="scope"></slot>
      </template>
      <template #summary>
        <slot name="summary"></slot>
      </template>
      <template #expandedRowRender="scope">
        <slot name="expandedRowRender" :scope="scope"></slot>
      </template>

    </a-table>
  </div>
</template>

<script setup>
import draggable from 'vuedraggable'
import { SettingOutlined, HolderOutlined, PushpinFilled, VerticalAlignBottomOutlined, VerticalAlignTopOutlined  } from '@ant-design/icons-vue'
import { onMounted, ref } from 'vue'
import { getLocalStorage } from '@/utils'
import { cloneDeep } from 'lodash'
import i18n from '@/locales/index'
const { t } = i18n.global
const emits = defineEmits(['change', 'columnsChange'])
let props = defineProps({
  storeTableName: {
    type: String,
    default: '',
    required: true,
  },
  size: {
    type: String,
    default: 'small',
  },
  rowKey: {
    type: String,
    default: 'key',
  },
  bordered: {
    type: Boolean,
    default: true,
  },
  dataSource: {
    type: Array,
    default: () => [],
  },
  columns: {
    type: Array,
    default: () => [],
  },
  loading: {
    type: Boolean,
    default: false,
  },
  rowSelection: {
    type: Object || null,
    default: () => null,
  },
  pagination: {
    type: [Object, Boolean],
    default: () => false,
  },
  scroll: {
    type: Object || null,
    default: () => null,
  },
  operateMargin: {
    type: Boolean,
    default: false,
  },
  showMore: {
    type: Boolean,
    default: false,
  },
  customRow: {
    type: [Function, null],
    default: () => null,
  },
  rowClassName: {
    type: [Function, null],
    default: () => null,
  },
  resizeColumns: {
    type: Boolean,
    default: false,
  },
  columnFilter: {
    type: [Object, null],
    default: () => null,
  },
  defaultExpandAllRows: {
    type: Boolean,
    default: false,
  },
  expandedRowKeys: {
    type: Array,
    default: () => [],
  },
  dataSourceEx: {
    type: Array,
    default: () => [],
  },
})
let tableColumns = ref(cloneDeep(props.columns))
let columnList = ref([])
const getColumns = () => {
  return columnList.value.filter((i) => i.visibility)
}
const onMove = (e) => {
  if (e.relatedContext.element.fixed) return false
  return true
}
const upDataColumn = () => {
  emits('columnsChange', columnList.value)
  localStorage.setItem(props.storeTableName, JSON.stringify(columnList.value))
} 
const fixColumnChange = (item, fixVal) => {
  item.fixed = fixVal
  const leftFixeds = columnList.value.filter((item) => item.fixed === 'left')
  const rightFixeds = columnList.value.filter((item) => item.fixed === 'right')
  const noFixeds = columnList.value.filter(
    (item) => !['right', 'left'].includes(item.fixed)
  ) 
  const newColumns = [...leftFixeds, ...noFixeds, ...rightFixeds]
  columnList.value = newColumns
  upDataColumn()
}
const handleResizeColumn = (w, col) => {
  if (props.resizeColumns) {
    col.width = w
    localStorage.setItem(props.storeTableName, JSON.stringify(columnList.value))
  }
}
const init = (data) => {
  let ary = [...data]
  if(props.columnFilter) {
    let {text, val}  = props.columnFilter
    console.log("🚀 ~ file: customTable.vue:165 ~ init ~ val:", val)
    if(!val) {
      ary = ary.filter((i) => !i[text])
    } else {
      if(getLocalStorage(props.storeTableName)?.length !=  props.columns.length)  ary =  props.columns
    }
  }
  ary.forEach((item) => {
    if(item.title18) item.title = t(item.title18)
    const target = tableColumns.value.find((i) => item.dataIndex === i.dataIndex)
    if(target) {
      const keys = Reflect.ownKeys(target)
      keys.forEach((key) => {
        if (typeof target[key] === 'function') {
          item[key] = target[key]
        }
      })
      item.visibility = item.visibility == undefined ? true : item.visibility
    }
  })

  return ary
}
onMounted(() => {
  const targetColums = getLocalStorage(props.storeTableName) || props.columns
  let columnAry = init(targetColums)
  columnList.value = columnAry
  emits('columnsChange', columnList.value)
})
</script>

